home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Games / NeXTGo / Source / igsparse.c < prev    next >
C/C++ Source or Header  |  1993-02-08  |  12KB  |  549 lines

  1. #include "comment.header"
  2. #include "igs.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7.  
  8. #define prompts Prompts
  9. #include "shared.h"
  10.  
  11. extern char *getloginname();
  12. extern char *getpassword();
  13. int loggedon;
  14. int repeatpass, repeatlogin;
  15. State state_t;
  16. int verts[3][MAX_BRD_SZ+1], num_ranks;
  17. char *ranks[50];
  18.  
  19. #ifdef STRSTR
  20. char *strstr();
  21. #endif
  22.  
  23. #ifdef STRTOL
  24. long strtol();
  25. #endif
  26.  
  27. char *Prompts[] =
  28. {
  29.   "Login: ",
  30.   "Password: ",
  31.   "Password: ",
  32.   "Enter Your Password Again: ",
  33.   "Enter your e-mail address (None): ",
  34.   "#> ",
  35.   "#> ",
  36.   "Enter Dead Group: ",
  37.   "#> ",
  38.   "#> ",
  39. };
  40.  
  41.  
  42. void initparser()
  43. {
  44.   loggedon = 0;
  45.   repeatpass = 0;
  46.   repeatlogin = 0;
  47. }
  48.  
  49.  
  50. int DoState(char *s)
  51. {
  52.   if (strncmp(s, Prompts[LOGON], strlen(Prompts[LOGON])) == 0)
  53.     return LOGON;
  54.   if (strncmp(s, "1 1", 3) == 0)
  55.     return PASSWORD;
  56.   if (strncmp(s, "1 0", 3) == 0)
  57.     return LOGON;
  58.   if (strncmp(s, Prompts[PASSWORD], strlen(Prompts[PASSWORD])) == 0)
  59.     return PASSWORD;
  60.   if (strncmp(s, Prompts[PASSWD_NEW], strlen(Prompts[PASSWD_NEW])) == 0)
  61.     return PASSWD_NEW;
  62.   if (strncmp(s, Prompts[PASSWD_CONFIRM],
  63.           strlen(Prompts[PASSWD_CONFIRM])) == 0)
  64.     return PASSWD_CONFIRM;
  65.   if (strncmp(s, Prompts[WAITING], strlen(Prompts[WAITING])) == 0)
  66.     return WAITING;
  67.   return -1;
  68. }
  69.  
  70. static long appending = 0;
  71.  
  72. char retbuf[1000];
  73. int idle;
  74.  
  75. int getmessage(message *mess, int uninitiated)
  76. {
  77.   char mesg[2000];
  78.   int ret;
  79.   char *textpart;
  80.   
  81.   idle = 0;
  82.   if (!uninitiated)
  83.     pollserver();
  84.   strcpy(mesg, retbuf);
  85.  
  86.   switch (DoState(mesg)) {
  87.   case PASSWD_NEW:
  88.   case PASSWD_CONFIRM:
  89.   case PASSWORD:
  90.     sendstr(getpassword(repeatpass++));
  91.     sendstr("\n");
  92.     break;
  93.   case WAITING:
  94.     sendstr("toggle client true\n");
  95.     mess->id = ONSERVER;
  96.     loggedon = 1;
  97.     sendstr("chars #O.?-++\n");
  98.     return 1;
  99.   case LOGON:
  100.     {
  101.       int needlogin;
  102.       needlogin = 1;
  103.       do {
  104.     if (needlogin == 1) {
  105.       sendstr(getloginname(repeatlogin++));
  106.       sendstr("\n");
  107.       needlogin = -1;
  108.     }
  109.     ret = pollserver();
  110.     strcpy(mesg, retbuf);
  111.     if (ret < 0)
  112.       return ret;
  113.     if (!strncmp(mesg, "Password:", 9) || (!strncmp(mesg, "1 1", 3)))
  114.       needlogin = 0;
  115.     else if (!strncmp(mesg, "Sorry", 5)) {
  116.       puts(mesg);
  117.       return 0;
  118.     } else if (strlen(mesg) > 2 && strncmp(mesg, "Login", 5))
  119.       puts(mesg);
  120.       } while (needlogin);
  121.       sendstr(getpassword(repeatpass++));
  122.       sendstr("\n");
  123.       do {
  124.     ret = pollserver();
  125.     strcpy(mesg, retbuf);
  126.     if (ret < 0)
  127.       return ret;
  128.     if (!strncmp(mesg, "Enter", 5)) {
  129.       sendstr(getpassword(repeatpass++));
  130.       sendstr("\n");
  131.     }
  132.     if (!strncmp(mesg, "9 File", 6))
  133.       needlogin = -1;
  134.     if (!strncmp(mesg, "To get", 6))
  135.       needlogin = 1;
  136.     if (!strncmp(mesg, "#>", 2)) {
  137.       sendstr("toggle client true\n");
  138.       mess->id = ONSERVER;
  139.       loggedon = 1;
  140.       sendstr("chars #O.?-++\n");
  141.       return 1;
  142.     }
  143.     if (!strncmp(mesg, "Invalid", 7)) {
  144.       puts(mesg);
  145.       needlogin = 1;
  146.     }
  147.       } while (!needlogin);
  148.       
  149.       if (needlogin > 0)
  150.     break;
  151.     }            /* intentional fall through occurs here */
  152.   default:
  153.     mess->id = strtol(mesg, &textpart, 10);
  154.     textpart++;
  155.     if (mess->id == 2 && (strstr(textpart, "Game")
  156.               || strstr(textpart, "min")))
  157.       mess->id = TIMEREP;
  158.     if (appending == -1) {
  159.       if (mess->id && !strncmp(textpart, "File", 4)) {
  160.     appending = 0;
  161.     if (!strncmp(mess->text, "                *=============", 29))
  162.       mess->id = QUITMESG;
  163.     return 1;
  164.       }
  165.       if (strlen(mess->text))
  166.     strcat(mess->text, "\n");
  167.       {
  168.     int len;
  169.     char *pt;
  170.     len = strlen(mesg);
  171.     pt = mesg;
  172.     while (len > 0) {
  173.       strncat(mess->text, pt, 79);
  174.       len -= 79;
  175.       pt += 79;
  176.       mess->lines++;
  177.       if (len > 0)
  178.         strcat(mess->text, "\n");
  179.     }
  180.       }
  181.       return 0;
  182.     }
  183.     if (mess->id == PROMPT) {
  184.       if (*textpart == '5' && !loggedon)
  185.     loggedon = 1;
  186.       if (appending == LOOK_M) {
  187.     mess->id = LOOK_M;
  188.     appending = 0;
  189.     return 1;
  190.       }
  191.       if (appending && !(appending == SCORE && mess->bscore == -10000)) {
  192.     mess->id = appending;
  193.     appending = 0;
  194.     return 1;
  195.       }
  196.       mess->prompttype = atoi(textpart);
  197.     }
  198.     if (!strcmp(textpart, "File" /* , 4 */ )) {
  199.       appending = -1;
  200.       strcpy(mess->text, "");
  201.       mess->lines = 0;
  202.       return 0;
  203.     }
  204.     if (mess->id == BEEP) {
  205.       mess->beep = (*textpart == 7);
  206.     }
  207.     if (mess->id == KIBITZ) {
  208.       if (parsekibitz(textpart, mess))
  209.     return 0;
  210.     }
  211.     if (mess->id == UNDO)
  212.       if (ret = parseundo(textpart, &(mess->gamenum))) {
  213.     if (ret < 0)
  214.       return ret;
  215.     return 0;
  216.       }
  217.     if (mess->id == MOVE)
  218.       if (parsemove(textpart, &(mess->x), &(mess->y), &(mess->movenum),
  219.             &(mess->gamenum), &(mess->color), &(mess->bcap), &(mess->btime),
  220.             &(mess->bbyo), &(mess->wcap), &(mess->wtime), &(mess->wbyo)
  221.             ))
  222.     mess->id = 0;
  223.     
  224.     if (mess->id == WHO) {
  225.       appending = WHO;
  226.       parsewho(mess, textpart);
  227.       return 0;
  228.     }
  229.     if (mess->id == GAMES) {
  230.       appending = GAMES;
  231.       parsegame(mess, textpart);
  232.       return 0;
  233.     }
  234.     if (mess->id == LOOK_M) {
  235.       appending = LOOK_M;
  236.       parsescore(mess, textpart);
  237.       return 0;
  238.     }
  239.     if (mess->id == SCORE) {
  240.       appending = SCORE;
  241.       parsescore(mess, textpart);
  242.       return 0;
  243.     }
  244.     strcpy(mess->text, textpart);
  245.     mess->lines = 1;
  246.     if (mess->id == INFO)
  247.       if (ret = parseinfo(textpart, mess))
  248.     return ret;
  249.     return 1;
  250.   }
  251.   return 0;
  252.   
  253. }
  254.  
  255. #ifdef STRTOL
  256. long strtol(char *text, char **new, int dum)
  257. {
  258.   long retu;
  259.   retu = atol(text);
  260.   for (*new = text; *new && **new <= '9' && **new >= '0'; (*new)++);
  261.   return retu;
  262. }
  263. #endif
  264.  
  265.  
  266.  
  267. #ifdef STRSTR
  268. char *strstr(char *s1, char *s2)
  269. {
  270.   register char *temp;
  271.   int len;
  272.   
  273.   temp = s1;
  274.   len = strlen(s2);
  275.   while (temp = strchr(temp, *s2)) {
  276.     if (!strncmp(temp, s2, len))
  277.       return temp;
  278.     else
  279.       temp++;
  280.   }
  281.   return NULL;
  282. }
  283. #endif
  284.  
  285.  
  286. void parsescore(message *mesg, char *s)
  287. {
  288.   char *bd;
  289.   int i;
  290.   
  291.   bd = strstr(s, ">>");
  292.   if (bd)
  293.     *(bd + 1) = '|';
  294.   bd = strstr(s, "<<");
  295.   if (bd)
  296.     *bd = '|';
  297.   if (strstr(s, "H-cap")) {
  298.     mesg->boardline = 0;
  299.     mesg->bscore = -10000;
  300.   } else if (bd = strchr(s, '|')) {
  301.     for (bd++, i = 0; *(bd - 1) != '|' || i == 0; bd += 2, i++) {
  302.       if (i >= mesg->boardsize)
  303.     mesg->boardsize = i + 1;
  304.       if (i < 19 && mesg->boardline < 19)
  305.     switch (*bd) {
  306.     case '.':
  307.       mesg->board[i][mesg->boardline] = EMPTY;
  308.       break;
  309.     case '#':
  310.       mesg->board[i][mesg->boardline] = BLACK;
  311.       break;
  312.     case 'O':
  313.       mesg->board[i][mesg->boardline] = WHITE;
  314.       break;
  315.     case '-':
  316.       mesg->board[i][mesg->boardline] = WTERR;
  317.       break;
  318.     case '+':
  319.       mesg->board[i][mesg->boardline] = BTERR;
  320.       break;
  321.     case '?':
  322.       mesg->board[i][mesg->boardline] = DAME;
  323.       break;
  324.     }
  325.     }
  326.     mesg->boardline++;
  327.   } else
  328.     sscanf(s, "%*[^ ] (W:O): %f to %*[^ ] (B:#): %f",
  329.        &(mesg->wscore), &(mesg->bscore));
  330.   if (bd = strstr(s, "Captured by #"))
  331.     mesg->wcap = atoi(bd + strlen("Captured by #: "));
  332.   if (bd = strstr(s, "Captured by O"))
  333.     mesg->bcap = atoi(bd + strlen("Captured by O: "));
  334. }
  335.  
  336.  
  337. void parsewho(message *mesg, char *str)
  338. {
  339.   if (!strncmp(str, "Info", 4)) {
  340.     strcpy(mesg->text, str);
  341.     mesg->lines = 1;
  342.   } else {
  343.     strcat(mesg->text, "\n");
  344.     strcat(mesg->text, str);
  345.     mesg->lines++;
  346.   }
  347. }
  348.  
  349.  
  350. void parsegame(message *mesg, char *str)
  351. {
  352.   int fieldcount;
  353.   char *br, *wr, blackrank[5], whiterank[5];
  354.   
  355.   if (str[1] == '#') {
  356.     mesg->gamecount = 0;
  357.     strcpy(mesg->text, str);
  358.     mesg->lines = 1;
  359.   } else {
  360.     strcat(mesg->text, "\n");
  361.     strcat(mesg->text, str);
  362.     mesg->lines++;
  363.     fieldcount = sscanf(str, "[%3d]%12s [%4c] vs.%12s [%4c] (%3d %d %d %f)\n",
  364.             &(mesg->gamelist[mesg->gamecount].gnum),
  365.             mesg->gamelist[mesg->gamecount].white,
  366.             whiterank,
  367.             mesg->gamelist[mesg->gamecount].black,
  368.             blackrank,
  369.             &(mesg->gamelist[mesg->gamecount].mnum),
  370.             &(mesg->gamelist[mesg->gamecount].bsize),
  371.             &(mesg->gamelist[mesg->gamecount].hcap),
  372.             &(mesg->gamelist[mesg->gamecount].komi));
  373.     
  374.     br = blackrank;
  375.     wr = whiterank;
  376.     br[4] = br[4] = 0;
  377.     if (*br == ' ')
  378.       br++;
  379.     if (*wr == ' ')
  380.       wr++;
  381.     if (br[strlen(br)-1] == ' ')
  382.       br[strlen(br)-1] = 0;
  383.     if (wr[strlen(wr)-1] == ' ')
  384.       wr[strlen(wr)-1] = 0;
  385.     strcpy(mesg->gamelist[mesg->gamecount].wrank, wr);
  386.     strcpy(mesg->gamelist[mesg->gamecount].brank, br);
  387.     if (fieldcount == 9)
  388.       (mesg->gamecount)++;
  389.   }
  390. }
  391.  
  392.  
  393. int parseinfo(char *s, message *mess)
  394. {
  395.   int ret, row;
  396.   extern int MAXY;
  397.   extern void igsbeep();
  398.   char col;
  399.   char text[100];
  400.  
  401.   if (2 == sscanf(s, "Match[%dx%d]", &ret, &ret)) {
  402.     igsbeep();
  403.     return 0;
  404.   }
  405.   if (1 == sscanf(s, "Match [%d]", &(mess->gamenum))) {
  406.     mess->id = MATCH;
  407.     return 0;
  408.   }
  409.   if (1 == sscanf(s, "Creating match [%d]", &(mess->gamenum))) {
  410.     mess->id = MATCH;
  411.     return 0;
  412.   }
  413.   if (2 == sscanf(s, "Removing @ %c%d", &col, &row)) {
  414.     
  415.     if (col > 'I')
  416.       col--;
  417.     mess->x = col - 'A';
  418.     mess->y = MAXY - row;
  419.     mess->id = REMOVE;
  420.     return 0;
  421.   }
  422.   if (!strncmp(s, "Board is restored", 17)) {
  423.     mess->id = SCOREUNDO;
  424.     return 0;
  425.   }
  426.   if (strstr(s, "has restored your old game.")) {
  427.     mess->id = LOAD;
  428.     ret = pollserver();
  429.     strcpy(text, retbuf);
  430.     if (ret < 0)
  431.       return ret;
  432.     ret = pollserver();
  433.     strcpy(text, retbuf);
  434.     if (ret < 0)
  435.       return ret;
  436.     ret = sscanf(text, "%*d Game %d: %*[^(](%d %d %d) vs %*[^(](%d %d %d)",
  437.          &(mess->gamenum), &(mess->bcap), &(mess->btime),
  438.          &(mess->bbyo), &(mess->wcap), &(mess->wtime), &(mess->wbyo)
  439.          );
  440.     ret = pollserver();
  441.     strcpy(text, retbuf);
  442.     if (ret < 0)
  443.       return ret;
  444.     return 0;
  445.   }
  446.   return 0;
  447. }
  448.  
  449.  
  450. static int gamenumber = -1;
  451.  
  452. /* Undo in game 0: zzz vs anthony:  D11 */
  453. /* Game 0: testa (0 0 0) vs testb (0 0 0) with move line afterwords */
  454.  
  455. int parseundo(char *s, int *gamenum)
  456. {
  457.   char mes[2000];
  458.   int count;
  459.   int bogus2, ret;
  460.   char bogus1;
  461.   
  462.   count = sscanf(s, "%*[^ ] undid the last move (%c%d).", &bogus1, &bogus2);
  463.   if (count == 2) {
  464.     ret = pollserver();
  465.     strcpy(mes, retbuf);
  466.     if (ret < 0)
  467.       return ret;
  468.     ret = pollserver();
  469.     strcpy(mes, retbuf);
  470.     if (ret < 0)
  471.       return ret;
  472.     
  473.     sscanf(mes, "%*d Game %d", gamenum);
  474.     ret = pollserver();
  475.     strcpy(mes, retbuf);
  476.     if (ret < 0)
  477.       return ret;
  478.     return 0;
  479.   }
  480.   count = sscanf(s, "Undo in game %d", gamenum);
  481.   if (count != 1)
  482.     return 1;            /* extra line */
  483.   return 0;
  484. }
  485.  
  486.  
  487. /* new format:  ## game gamenum: plr (cap time byo) vs plr (cap time byo) */
  488.  
  489. int parsekibitz(char *s, message *mess)
  490. {
  491.   if (1 == sscanf(s, "Kibitz %[^:]", mess->kibitzer))
  492.     return 1;
  493.   while (*s == ' ')
  494.     s++;
  495.   strcpy(mess->kibitz, s);
  496.   return 0;
  497.   
  498. }
  499.  
  500.  
  501. int parsemove(char *s, int *x, int *y, int *mv, int *gm, int *color, int *bcap,
  502.           int *btime, int *bbyo, int *wcap, int *wtime, int *wbyo)
  503. {
  504.   int mc;
  505.   char c, col;
  506.   extern int MAXY, handicap;
  507.   
  508.   mc = sscanf(s, "%3d(%c): %c%d", mv, &c, &col, y);
  509.   if (mc == 3) {
  510.     if (3 == sscanf(s, "%3d(%c): Handicap %d", mv, &c, &mc)) {
  511.       handicap = mc;
  512.       *x = *y = mc + 100;
  513.       *gm = gamenumber;
  514.       *color = c == 'W' ? WHITE : BLACK;
  515.       (*mv)++;
  516.       return 0;
  517.     }
  518.     if (2 == sscanf(s, "%3d(%c): Pass", mv, &c)) {
  519.       *x = *y = -1;
  520.       *gm = gamenumber;
  521.       *color = c == 'W' ? WHITE : BLACK;
  522.       (*mv)++;
  523.       return 0;
  524.     }
  525.   }
  526.   if (mc != 4) {
  527.     sscanf(s, "Game %d: %*[^(](%d %d %d) vs %*[^(](%d %d %d)",
  528.        &gamenumber, wcap, wtime, wbyo, bcap, btime, bbyo);
  529.     return 1;
  530.   }
  531.   if (col > 'I')
  532.     col--;
  533.   *x = col - 'A';
  534.   *y = MAXY - *y;
  535.   *color = c == 'W' ? WHITE : BLACK;
  536.   *gm = gamenumber;
  537.   (*mv)++;
  538.   return 0;
  539. }
  540.  
  541.  
  542. int doneline(char *inbuf, int inptr)
  543. {
  544.   return !loggedon &&
  545.     (inptr > 0 && inbuf[inptr - 1] == ' ') &&
  546.       ((inptr > 1 && inbuf[inptr - 2] == ':') ||
  547.        (inptr > 2 && inbuf[inptr - 2] == '>' && inbuf[inptr - 3] == '#'));
  548. }
  549.